from django.http import HttpResponse
from django.conf import settings
from django.core.cache import cache
from django.utils.timezone import now
from django.core.serializers import serialize
from django.db.models import Sum
from django.db.models.functions import Trunc
from django.db.models import Count, DateTimeField

import json, jwt, time, copy, datetime
# from datetime import datetime, timedelta

from ...models.admin_users import AdminUsers
from ...models.users import Users
from ...models.chat_items import ChatItems
from ...models.chat_history import ChatHistory
from ...models.chat_orders import ChatOrders
from ...utils.users import generate_salt, create_password_hash, get_login_user_id
from ...utils.time_conversion import iso_to_times


def login(request):
    '''
    后台登陆
    post
    body = {
        "username": "admin",
        "password": "admin123"
    }
    res = {
        "code": 0,
        "data": {
            "is_super_admin": true,
            "token": "..."
        }
    }
    '''
    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        uname = json_obj['username']
        upass = json_obj['password']
        try:
            re_user_obj = AdminUsers.objects.get(username=uname)
        except AdminUsers.DoesNotExist:
            res_mes = {
                "code": 1,
                "message": "用户名不存在"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json) 

        
        login_pass = create_password_hash(upass, re_user_obj.salt)
        if login_pass != re_user_obj.password:
            res_mes = {
                "code": 1,
                "message": "用户名或密码错误"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        if not re_user_obj.status and re_user_obj.id != 1:
            res_mes = {
                "code": 1,
                "message": "该用户已被禁止登录，请联系超级管理员"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 创建 token
        now_time = time.time()
        expired_time = now_time + settings.MY_TOKEN_CONF['MAXAGE']
        payload_json = {
            "user_id": re_user_obj.id,
            "username": re_user_obj.username,
            "expired": expired_time,
            "isadminapi": True
        }
        # 加密
        try:
            token_str = jwt.encode(payload_json, settings.MY_TOKEN_CONF['SECRETKEY'])
        except Exception as e:
            res_mes = {
                "code": 1,
                "message": "Failed to generate token：{e}"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 把token存入redis
        mes_key = "admin/%s" % re_user_obj.id
        try:
            cache.set(mes_key, token_str, timeout=settings.MY_TOKEN_CONF['MAXAGE'])
        except Exception as e:
            res_mes = {
                "code": 1,
                "message": "Failed to generate token：{e}"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 更新最后登录时间和IP
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            client_ip = x_forwarded_for.split(',')[0]
        else:
            client_ip = request.META.get('REMOTE_ADDR')

        re_user_obj.last_login_ip = client_ip
        re_user_obj.last_login_at = datetime.datetime.now()
        
        # 更新数据
        try:
            re_user_obj.save()
        except Exception as e:
            res_mes = {
                "code": 1,
                "message": "保存数据失败！"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        # 返回数据
        if re_user_obj.id == 1:
            is_super_admin = "true"
        else:
            is_super_admin = "false"
        res_mes = {
            "code": 0,
            "data": {
                "is_super_admin": is_super_admin,
                "token": token_str
            }
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def save_user(request):
    '''
    后台创建账号
    post
    body = {
        "username": "fanlichun",
        "password": "12345678",
        "repass": "12345678"
    }
    res = {
        "code": 0
    }
    '''

    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        uname = json_obj['username']
        upass = json_obj['password']

        re_user_obj = AdminUsers.objects.filter(username=uname)
        if re_user_obj:
            res_mes = {
                "code": 1,
                "message": "用户名已存在"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 生成加密盐
        salt = generate_salt(8)
        # 创建用户
        users_instance = AdminUsers()
        json_obj_users_linshi = {
            "username": uname,
            "password": create_password_hash(upass, salt),
            "salt": salt
        }
        for key, value in json_obj_users_linshi.items():
            code_str = "users_instance.%s = '%s'" % (key, value)
            exec(code_str)

        try:
            users_instance.save()
        except Exception as e:
            res_mes = {
                "code": 1,
                "message": e
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def session(request):
    '''
    session 会话检测
    '''
    userid = get_login_user_id(request, isadmin=True)
    mes_key = "admin/%s" % userid
    try:
        cache.get(mes_key)
    except Exception as e:
        res_mes = {
            "code": 1,
            "message": e
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)

    try:
         re_user_obj = AdminUsers.objects.get(id=userid)
    except AdminUsers.DoesNotExist:
        res_mes = {
            "code": 1,
            "message": "用户名不存在"
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json) 

    user_info_old = AdminUsers.objects.filter(id=userid).values(
        "id",
        "username",
        "status",
        "last_login_at",
        "created_at",
        "updated_at"
    )

    if not user_info_old:
        res_mes = {
            "code": 1,
            "message": "用户名不存在"
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json) 

    user_info_new = copy.deepcopy(user_info_old[0])

    created_at = user_info_old[0]['created_at']
    user_info_new['created_at'] = created_at.strftime("%Y-%m-%d %H:%M:%S")

    updated_at = user_info_old[0]['updated_at']
    user_info_new['updated_at'] = updated_at.strftime("%Y-%m-%d %H:%M:%S")

    last_login_at = user_info_old[0]['last_login_at']
    user_info_new['last_login_at'] = last_login_at.strftime("%Y-%m-%d %H:%M:%S")

    res_mes = {
        "code": 0,
        "data": user_info_new
    }
    res_mes_json = json.dumps(res_mes, ensure_ascii=False)
    return HttpResponse(res_mes_json)


def dashboard_stats(request):
    '''
    主页面，信息展示
    '''

    # 定义一个全局变脸
    stats = {}
    stats['chart'] = {}

    # 获取今日时间
    today_start = now().replace(hour=0, minute=0, second=0, microsecond=0)
    today_end = now().replace(hour=23, minute=59, second=59, microsecond=999999)

    #### 获取今日新增用户
    today_created_users = Users.objects.filter(created_at__range=(today_start, today_end))
    stats['users'] = len(today_created_users)

    #### 获取今日新增对话
    today_created_items = ChatItems.objects.filter(created_at__range=(today_start, today_end))
    stats['chats'] = len(today_created_items)

    #### 获取今日消耗tokens
    today_tokens = ChatHistory.objects.filter(created_at__range=(today_start, today_end)).aggregate(sum=Sum('tokens'))['sum'] or 0
    stats['tokens'] = today_tokens

    #### 获取今日收入
    # 还没写
    today_income = ChatOrders.objects.filter(updated_at__range=(today_start, today_end), status=2).aggregate(sum=Sum('amount'))['sum'] or 0
    stats['income'] = today_income

    # 获取过去7天日期
    # ['2024-08-23', '2024-08-22', '2024-08-21', '2024-08-20', '2024-08-19', '2024-08-18', '2024-08-17']
    current_date = now().date()
    dates = [str(current_date - datetime.timedelta(days=i)) for i in range(7)]
    dates.reverse()

    #### 统计用户7天增加的曲线
    # # 返回数据 "users": {
    #             "2024-08-17": 0,
    #             "2024-08-18": 0,
    #             "2024-08-19": 0,
    #             "2024-08-20": 0,
    #             "2024-08-21": 0,
    #             "2024-08-22": 0,
    #             "2024-08-23": 0
    #         }
    # <QuerySet [(datetime.datetime(2024, 8, 20, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 6), (datetime.datetime(2024, 8, 22, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 3)]>
    user_obj = Users.objects.annotate(
                    day=Trunc('created_at', 'day', output_field=DateTimeField())
                ).filter(
                    day__gte=now() - datetime.timedelta(days=7)
                ).values('day').annotate(
                    count=Count('id')
                ).values_list('day', 'count')


    if user_obj:
        # (datetime.datetime(2024, 8, 20, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 6)
        # queryset_dict = {'2024-08-20': 6, '2024-08-21': 7}
        queryset_dict = {}

        for obj in user_obj:
            # '2024-08-20'
            date_str = obj[0].strftime('%Y-%m-%d')
            queryset_dict[date_str] = obj[1]

        def data_hand(riqi):
            if riqi in queryset_dict:
                return queryset_dict[riqi]
            else:
                return 0

        stats['chart']["users"] = {item: data_hand(item) for item in dates}
    else:
        # 代表没有数据
        stats['chart']["users"] = {item: 0 for item in dates}


    #### 统计7天Token 消耗
    # <QuerySet [(datetime.datetime(2024, 8, 20, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 1), (datetime.datetime(2024, 8, 23, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 9)]>
    chathistory_obj = ChatHistory.objects.annotate(
                        day=Trunc('created_at', 'day', output_field=DateTimeField())
                    ).filter(
                        day__gte=now() - datetime.timedelta(days=7)
                    ).values('day').annotate(
                        total_tokens=Sum('tokens')
                    ).values_list('day', 'total_tokens')
    
    if chathistory_obj:
        # (datetime.datetime(2024, 8, 20, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 6)
        # queryset_dict = {'2024-08-20': 6, '2024-08-21': 7}
        queryset_dict = {}

        for obj in chathistory_obj:
            # '2024-08-20'
            date_str = obj[0].strftime('%Y-%m-%d')
            queryset_dict[date_str] = obj[1]

        def data_hand(riqi):
            if riqi in queryset_dict:
                return queryset_dict[riqi]
            else:
                return 0

        stats['chart']["historyMessage"] = {item: data_hand(item) for item in dates}
    else:
        # 代表没有数据
        stats['chart']["historyMessage"] = {item: 0 for item in dates}


    #### 统计7天收入 orders
    # <QuerySet [(datetime.datetime(2024, 8, 20, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 1), (datetime.datetime(2024, 8, 23, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 9)]>
    chatorders_obj = ChatOrders.objects.annotate(
                        day=Trunc('updated_at', 'day', output_field=DateTimeField())
                    ).filter(
                        day__gte=now() - datetime.timedelta(days=7)
                    ).values('day').annotate(
                        order=Sum('amount')
                    ).values_list('day', 'order')
    
    if chatorders_obj:
        # (datetime.datetime(2024, 8, 20, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Shanghai')), 6)
        # queryset_dict = {'2024-08-20': 6, '2024-08-21': 7}
        queryset_dict = {}

        for obj in chatorders_obj:
            # '2024-08-20'
            date_str = obj[0].strftime('%Y-%m-%d')
            queryset_dict[date_str] = obj[1]

        def data_hand(riqi):
            if riqi in queryset_dict:
                return queryset_dict[riqi]
            else:
                return 0

        stats['chart']["orders"] = {item: data_hand(item) for item in dates}
    else:
        # 代表没有数据
        stats['chart']["orders"] = {item: 0 for item in dates}


    # 最终返回的数据
    res_mes = {
        "code": 0,
        "data": stats
    }
    res_mes_json = json.dumps(res_mes, ensure_ascii=False)
    return HttpResponse(res_mes_json)


def adminuser_list(request):
    '''
    管理员用户 列表
    '''
    all_adminusers_obj = AdminUsers.objects.all().order_by('id')
    json_data_str = serialize('json', all_adminusers_obj)
    json_data = json.loads(json_data_str)

    data = []
    for i in range(len(json_data)):
        # 先删除不需要返回的字段
        del json_data[i]['fields']['password']
        del json_data[i]['fields']['salt']

        json_data[i]['fields']['id'] = json_data[i]['pk']

        # 数据处理
        created_at_second = iso_to_times(json_data[i]['fields']['created_at'])
        updated_at_second = iso_to_times(json_data[i]['fields']['updated_at'])
        json_data[i]['fields']['created_at'] = created_at_second
        json_data[i]['fields']['updated_at'] = updated_at_second
        
        if json_data[i]['fields']['last_login_at'] is None or not json_data[i]['fields']['last_login_at']:
            json_data[i]['fields']['last_login_at'] = ""
        else:
            last_login_at_second = iso_to_times(json_data[i]['fields']['last_login_at'])
            json_data[i]['fields']['last_login_at'] = last_login_at_second

        data.append(json_data[i]['fields'])

    # 返回数据
    res_mes = {
        "code": 0,
        "data": data
    }
    res_mes_json = json.dumps(res_mes, ensure_ascii=False)
    return HttpResponse(res_mes_json)


def adminuser_enable(request):
    '''
    修改状态
    body = {
        "id": 3,
        "enabled": false
    }
    '''
    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        try:
            AdminUsers.objects.filter(id=json_obj['id']).update(status=json_obj['enabled'])
        except Exception as e:
            res_mes = {
                "code": 1,
                "message": "数据库更新失败！"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def adminuser_remove(request):
    '''
    删除
    参数：id=3
    '''
    re_id = request.GET.get('id')
    try:
        del_obj = AdminUsers.objects.get(id=re_id)
        del_obj.delete()

        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)
    except Exception as e:
        res_mes = {
            "code": 1,
            "message": "删除失败！"
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def adminuser_resetpass(request):
    '''
    修改密码
    post
    body = {
        "id": 2,
        "password": "11111111"
    }
    '''
    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        adminusers_instance = AdminUsers.objects.get(id=json_obj['id'])
        adminusers_instance_salt = adminusers_instance.salt
        pass_hash = create_password_hash(json_obj['password'], adminusers_instance_salt)
        adminusers_instance.password = pass_hash

        try:
            adminusers_instance.save()
        except Exception as e:
            res_mes = {
                "code": 1,
                "message": "修改密码失败！"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def logout(request):
    '''
    GET
    logout
    '''
    userid = get_login_user_id(request, isadmin=True)
    mes_key = "admin/%s" % userid
    # 删除单个key
    try:
        cache.delete(mes_key)
    except Exception as e:
        res_mes = {
            "code": 1,
            "message": "退出登陆失败！"
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)
    
    # 返回数据
    res_mes = {
        "code": 0
    }
    res_mes_json = json.dumps(res_mes, ensure_ascii=False)
    return HttpResponse(res_mes_json)

